package com.dliyun.patchca;

import com.dliyun.patchca.color.SingleColorFactory;
import com.dliyun.patchca.filter.predefined.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.Base64;
import java.util.Random;


/**
 * @author jtoms
 */
public class PatchcaService {
    private final Logger log = LoggerFactory.getLogger(PatchcaService.class);

    private final PatchcaCacheService cacheService;

    public PatchcaService(PatchcaCacheService cacheService) {
        this.cacheService = cacheService;
    }

    public BufferedImage generateImage(String token) {
        try {
            ConfigurableCaptchaService cs = new ConfigurableCaptchaService();
            cs.setColorFactory(new SingleColorFactory(new Color(25, 60, 170)));
            Random random = new Random();
            switch (random.nextInt(4)) {
                case 0:
                    cs.setFilterFactory(new CurvesRippleFilterFactory(cs.getColorFactory()));
                    break;
                case 1:
                    cs.setFilterFactory(new MarbleRippleFilterFactory());
                    break;
                case 2:
                    cs.setFilterFactory(new DoubleRippleFilterFactory());
                    break;
                case 3:
                    cs.setFilterFactory(new WobbleRippleFilterFactory());
                    break;
                case 4:
                    cs.setFilterFactory(new DiffuseRippleFilterFactory());
                    break;
                default:
                    break;

            }

            Captcha captcha = cs.getCaptcha();
            this.cacheService.setValue(token, captcha.getChallenge());
            return captcha.getImage();
        } catch (Exception e) {
            // TODO: handle exception
            log.error("error", e);
            return null;
        }
    }

    /**
     * 产生一个验证码图片二进制流
     */
    public String generateCaptcha(String token) {
        try {
            BufferedImage image = generateImage(token);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(image, "png", baos);
            String data = Base64.getEncoder().encodeToString(baos.toByteArray());
            data = "data:image/png;base64," + data;
            return data;
        } catch (Exception e) {
            log.error("convert image to byte error: ", e);
        }
        return null;
    }

    /**
     * 比较验证码
     *
     * @param captcha
     * @param token
     * @param destroySession
     */
    public boolean compareCaptcha(String captcha, String token, boolean destroySession) {
        String extistCaptcha = this.cacheService.getValue(token);
        if (destroySession) {
            this.cacheService.removeValue(token);
        }
        log.debug("SESSION captcha " + extistCaptcha);
        log.debug("INPUT captcha " + captcha);
        return captcha != null && captcha.equalsIgnoreCase(extistCaptcha);
    }
}
